package mobi.ilabs.authentication;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.restlet.Client;
import org.restlet.data.ChallengeResponse;
import org.restlet.data.ChallengeScheme;
import org.restlet.data.Form;
import org.restlet.data.Method;
import org.restlet.data.Protocol;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.data.Status;
import org.restlet.resource.StringRepresentation;

/**
 *  Authenticate an account using HTTPS against google's standard
 *  account check.
 *
 *  XXX A reasonable extension to this class would be to extract the
 *      authentication cookie and then use that if further requests 
 *      are to be made on behalf of the user, but for now we have not
 *      added that functionality since it is not needed right now.
 */
public  class HttpGoogleAuthenticator implements  RawAuthenticator {


    /**
     * The hostname of the host to perform the authentication against.
     */
    private final String authHost;

    /**
     * Create a new instance of an HTTP authenticator.
     * @param hostname The host to authenticate against.
     */
    public HttpGoogleAuthenticator(final String hostname) {
        authHost = hostname;
    }


    /**
     * The application we are announcing to Google that we are
     * authenticating on behalf of.
     */
    public static final  String  APPLICATION_NAME = "restroom";

    /**
     * Our version number (to be announced to Google when authenticating).
     */
    public static final   String VERSION_ID       = "0.9";

    /**
     * Our company name (to be announced to Google when authenticating).
     */
    public static final String COMPANY_NAME       = "Telenor";


    /**
     *  Name of the service we're searching for authentication for.
     */
    public static final String SERVICE = "blogger";



    /**
     * Log instance used by this class.
     */
    private static final Log LOG =
        LogFactory.getLog(GoogleAccountAuthenticator.class);


    /**
     * Check if the user is authenticated against google's
     * username/password database.
     * @param userId The username.
     * @param secret The password.
     * @return the result of the authentication.
     */
    public AuthenticationResult rawAuthenticate (
            final String userId,
            final String secret) {


        final Form c = new Form();
        c.add("Email",   userId);
        c.add("Passwd",  secret);
        c.add("service", SERVICE);
        c.add("source",  COMPANY_NAME + '-'
                + APPLICATION_NAME + '-' + VERSION_ID);

        //
        // XXX I'm not encoding this as a POST request. That is ugly
        //     but for now that's how I'll do it (I couldn't figure out
        //     how to do this using a post request. When I do, I'll use Post
        //     instead.
        final String  queryURI  = authHost + "?" + c.getQueryString();
        final Request  request  = new Request(Method.GET, queryURI);
        final Client   client   = new Client(Protocol.HTTPS);
        final Response response = client.handle(request);
        final Status   status   = response.getStatus();

        AuthenticationResult result;
        if (status.isSuccess()) {
            result = AuthenticationResult.AUTHENTICATED;
        } else if (status.isError()) {
            result = AuthenticationResult.REJECTED;
        } else {
            result = AuthenticationResult.UNKNOWN;
        }

        LOG.debug("HTTP Authenticating user "
                + userId
                + " cred = "    + secret
                + " host = "    + authHost
                + ", result = " + result);

        return result;

    }
}
